package com.es.demo.service.impl;

import com.es.demo.constant.Constant;
import com.es.demo.domain.Article;
import com.es.demo.service.IArticleServer;
import com.es.demo.utils.UUIDHelper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.*;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

/**
 * @author shengtao
 * @Description:
 * @date 2018/10/31 19:23
 */
@Service
public class ArticleServiceImpl implements IArticleServer {

    Logger log = LoggerFactory.getLogger(ArticleServiceImpl.class);

    @Autowired
    private TransportClient client;


    @Override
    public Boolean isEmpty() {
        if (client == null) {
            log.info("is raight!");
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public Article save(String index, String type, Article article) throws IOException {
        XContentBuilder builder = jsonBuilder().startObject()
                .field("id", article.getId())
                .field("name", article.getName())
                .field("totalPage", article.getTotalPage())
                .field("desc", article.getDesc())
                .endObject();
        IndexResponse indexResponse = client.prepareIndex(index, type, UUIDHelper.genUUID()).setSource(builder).get();
        article.setId(indexResponse.getId());
        return article;
    }

    @Override
    public Article saveJson(String index, String type, Article article) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        byte[] json = mapper.writeValueAsBytes(article);
        IndexResponse indexResponse = client.prepareIndex(index, type, UUIDHelper.genUUID()).setSource(json).get();
        article.setId(indexResponse.getId());
        return article;
    }

    @Override
    public Article update(String index, String type, String id, Article article) throws IOException, ExecutionException, InterruptedException {
        UpdateRequest request = new UpdateRequest(index, type, id);
        request.doc(XContentFactory.jsonBuilder()
                .startObject()
                .field("totalPage", article.getTotalPage())
                .endObject());
        UpdateResponse response = client.update(request).get();
        article.setId(response.getId());
        return article;
    }

    @Override
    public Article delete(String index, String type, String id) {
        return null;
    }

    @Override
    public Article get(String index, String type, String id) throws IOException {
        GetResponse response = client.prepareGet(index, type, id).get();
        byte[] result = response.getSourceAsBytes();
        ObjectMapper mapper = new ObjectMapper();
        Article article = mapper.readValue(result,Article.class);
        return article;
    }

    @Override
    public List<Article> matchAllQuery() throws IOException {
        SearchResponse response = client.prepareSearch(Constant.INDEX).setSearchType(Constant.TYPE).setQuery(QueryBuilders.matchAllQuery()).get();
        ObjectMapper objectMapper = new ObjectMapper();
        SearchHits hits = response.getHits();
        List<Article> articles = new ArrayList<>();
        for (SearchHit hit:hits){
            String result = hit.getSourceAsString();
            articles.add(objectMapper.readValue(result,Article.class));
        }
        return articles;
    }

    @Override
    public List<Article> searchLike(Article article) throws IOException {
        SearchResponse response = client.prepareSearch(Constant.INDEX).setQuery(QueryBuilders.matchQuery("name",article.getName())).get();
        SearchHits hits = response.getHits();
        List<Article> articles = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        for (SearchHit hit:hits){
            String result = hit.getSourceAsString();
            articles.add(objectMapper.readValue(result,Article.class));
        }
        return articles;
    }

    @Override
    public List<Article> muiltiSearch(Article article) throws IOException {
        List<Article> articles = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        MultiSearchRequestBuilder builder = client.prepareMultiSearch();
        List<SearchRequestBuilder> requests = new ArrayList<>();
        if(article.getName() != null){
            SearchRequestBuilder searchRequestBuilder = client.prepareSearch(Constant.INDEX).setQuery(QueryBuilders.queryStringQuery(article.getName()));
            requests.add(searchRequestBuilder);
        }
        requests.stream().forEach(searchRequestBuilder -> {
            builder.add(searchRequestBuilder);
        });
        MultiSearchResponse response = builder.get();

        for (MultiSearchResponse.Item item : response.getResponses()){
            SearchResponse response1 = item.getResponse();
            SearchHits hits = response1.getHits();
            for (SearchHit hit:hits){
                String result = hit.getSourceAsString();
                articles.add(objectMapper.readValue(result,Article.class));
            }
        }
        return articles;
    }
}
